package com.hyg.module_third_party_demo.activity;


import android.os.Bundle;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.hyg.lib_common.Base.BaseActivity;
import com.hyg.lib_common.constant.Constants;
import com.hyg.module_third_party_demo.R;
import com.hyg.module_third_party_demo.entity.FastJsonTest;
import com.hyg.module_third_party_demo.entity.User;

import java.util.Map;

import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.HTTP;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Path;
import retrofit2.http.Query;
import retrofit2.http.Url;


@Route(path = Constants.PATH_ACTIVITY_MODULE_DEMO_RETROFIT)
public class RetrofitActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_retrofit);
        init();
    }

    public void init() {

    }

    public interface GetRequest_Interface {
        @GET("openapi.do?keyfrom=abc&key=2032414398&type=data&doctype=json&version=1.1&q=car")
        Call<FastJsonTest> getCall(@Field("name") String name);
        // @GET注解的作用:采用Get方法发送网络请求
        // getCall() = 接收网络请求数据的方法
        // 其中返回类型为Call<*>，*是接收数据的类（即上面定义的Translation类）
        // 如果想直接获得Responsebody中的内容，可以定义网络请求返回值为Call<ResponseBody>

        @POST("FastJsonTest")
        Call<FastJsonTest> postCall(@Field("name") String name);

        /**
         * method：网络请求的方法（区分大小写）
         * path：网络请求地址路径
         * hasBody：是否有请求体
         */
        @HTTP(method = "GET", path = "blog/{id}", hasBody = false)
        Call<ResponseBody> getCall(@Path("id") int id);
        // {id} 表示是一个变量
        // method 的值 retrofit 不会做处理，所以要自行保证准确

        /**注释
         //1.@GET、@POST、@PUT、@DELETE、@HEAD分别对应 HTTP中的网络请求方式
         //2.@HTTP替换@GET、@POST、@PUT、@DELETE、@HEAD注解的作用 及 更多功能拓展

         /**标记：*/
        /**1.@FormUrlEncoded*/
        //表示发送form-encoded的数据，每个键值对需要用@Filed来注解键名，随后的对象需要提供值。
        /**2.@Multipart*/
        //表示发送form-encoded的数据（适用于 有文件 上传的场景），每个键值对需要用@Part来注解键名，随后的对象需要提供值。

        //网络请求参数
        /**1.@Header & @Headers     添加请求头 &添加不固定的请求头*/
        @GET("user")
        Call<User> getUser(@Header("Authorization") String authorization);

        @Headers("Authorization: authorization")
        @GET("user")
        Call<User> getUser();

        /**2.@Body   以Post方式传递自定义数据类型 给服务器,如果提交的是一个Map，那么作用相当于 @Field,不过Map要经过 FormBody.Builder 类处理成为符合 Okhttp 格式的表单，如：*/
        //FormBody.Builder builders = new FormBody.Builder();
        //builders.add("key","value");

        /**3.@Field & @FieldMap      发送 Post请求 时提交请求的表单字段,与 @FormUrlEncoded 注解配合使用*/
        /** <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值*/
        @POST("/form")
        @FormUrlEncoded
        Call<ResponseBody> testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);

        /**
         * Map的key作为表单的键
         */
        @POST("/form")
        @FormUrlEncoded
        Call<ResponseBody> testFormUrlEncoded2(@FieldMap Map<String, Object> map);


        /**4.@Part & @PartMap*/
        /**发送 Post请求 时提交请求的表单字段,与@Field的区别：功能相同，但携带的参数类型更加丰富，包括数据流，所以适用于 有文件上传 的场景,与 @Multipart 注解配合使用*/
        @POST("/form")
        @Multipart
        Call<ResponseBody> testFileUpload2(@PartMap Map<String, RequestBody> args, @Part MultipartBody.Part file);

        @POST("/form")
        @Multipart
        Call<ResponseBody> testFileUpload3(@PartMap Map<String, RequestBody> args);


        /**5.@Query和@QueryMap*/
        /**用于 @GET 方法的查询参数（Query = Url 中 ‘?’ 后面的 key-value） 如：url = http://www.println.net/?cate=android，
         * 其中，Query = cate 配置时只需要在接口方法中增加一个参数即可：*/
        @GET("/")
        Call<String> cate(@Query("cate") String cate);

        /**6.@Path   URL地址的缺省值*/
        @GET("users/{user}/repos")
        Call<ResponseBody>  getBlog(@Path("user") String user);
        // 访问的API是：https://api.github.com/users/{user}/repos
        // 在发起请求时， {user} 会被替换为方法的第一个参数 user（被@Path注解作用）

        /**7.@Url 直接传入一个请求的 URL变量 用于URL设置*/
        @GET
        Call<ResponseBody> testUrlAndQuery(@Url String url, @Query("showAll") boolean showAll);
        // 当有URL注解时，@GET传入的URL就可以省略
        // 当GET、POST...HTTP等方法中没有设置Url时，则必须使用 {@link Url}提供
    }

    /**
     * description: 开始网络请求
     *
     * @author visitant
     * @time 2020/11/17 16:00
     */
    public void startHttp() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fanyi.youdao.com/") //设置网络请求的Url地址
//                .addConverterFactory(GsonConverterFactory.create()) //设置数据解析器
//                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
//      Call<FastJsonTest> call = request.getCall("");
        Call<FastJsonTest> call = request.postCall("");
        call.enqueue(new Callback<FastJsonTest>() {
            //请求成功时回调
            @Override
            public void onResponse(Call<FastJsonTest> call, Response<FastJsonTest> response) {
                //请求处理,输出结果
                response.body().toString();
            }

            //请求失败时候的回调
            @Override
            public void onFailure(Call<FastJsonTest> call, Throwable throwable) {
                System.out.println("连接失败");
            }
        });
//        //同步请求
//        try {
//            Response<FastJsonTest> response = call.execute();
//            response.body().toString();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }


}